/**
 * 
 */
package com.sidom.movieIndexer.domain.imdb;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;

import static org.apache.commons.lang.Validate.notNull;

/**
 * A class representing imdb information about a movie.
 * @author Siebe
 */
public class ImdbResult {
	/**
	 * The list of possible labels.
	 * 
	 * E.g.: A list of the H5 values in the case below: Tagline
	 * <div class="info">
	 *		<h5>Tagline:</h5>
	 *			<div class="info-content">Ice Cold, Hot Wired. <a onclick="(new Image()).src='/rg/title-tease/taglines/images/b.gif?link=/title/tt0187078/taglines';" href="/title/tt0187078/taglines" class="tn15more inline" linkindex="161">more</a>
	 *			</div>
	 *	</div>
	 */
	public enum Label{
		DIRECTOR("director"),
		WRITER("writer"),
		RELEASE_DATE("release date"),
		GENRE("genre"),
		TAG_LINE("tagline"),
		PLOT("plot"),
		PLOT_KEYWORD("plot keyword"),
		USER_REVIEW("user review"),
		CAST("cast");
		
		/**
		 * The name of the label.
		 */
		private final String label;
		
		/**
		 * Constructor.
		 * @param label The label name.
		 */
		private Label(String label){
			this.label = label;
		}

		/**
		 * @return the label
		 */
		public String getLabel() {
			return label;
		}
	}
	
	/**
	 * The url of the cover image.
	 */
	private String coverUrl;
	/**
	 * The imdb title of the movie.
	 */
	private String title;
	/**
	 * The year the movie was made.
	 */
	private String year;
	/**
	 * The user rating the movie recieved.
	 */
	private String userRating;
	/**
	 * The directors of the movie.
	 */
	private List<String> directors;
	/**
	 * The release date of the movie.
	 */
	private String releaseDate;
	/**
	 * The release date of the movie.
	 */
	private String tagLine;
	/**
	 * The plot of the movie.
	 */
	private String plot;
	/**
	 * The plot key words of the movie.
	 */
	private List<String> plotKeyWords;
	/**
	 * The best movie review of the movie.
	 */
	private String userReview;
	/**
	 * The writers of the movie.
	 */
	private List<String> writers;
	/**
	 * The cast members of the movie.
	 */
	private List<Cast> castMembers;
	/**
	 * The genres of of the movie.
	 */
	private List<String> genres;
	
	/**
	 * Constructor.
	 * Uses Builder pattern.
	 * @param builder
	 */
	public ImdbResult(Builder builder) {
		super();
		notNull(builder, "Builder should not be null");
		this.coverUrl 		= builder.coverUrl;
		this.title 			= builder.title;
		this.year 			= builder.year;
		this.userRating 	= builder.userRating;
		this.directors 		= builder.directors;
		this.writers 		= builder.writers;
		this.releaseDate 	= builder.releaseDate;
		this.tagLine 		= builder.tagLine;
		this.plot 			= builder.plot;
		this.plotKeyWords 	= builder.plotKeyWords;
		this.userReview 	= builder.userReview;
		this.castMembers 	= builder.castMembers;
		this.genres 		= builder.genres;
	}
	/**
	 * @return the coverUrl
	 */
	public String getCoverUrl() {
		return coverUrl;
	}
	/**
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}
	/**
	 * @return the year
	 */
	public String getYear() {
		return year;
	}
	/**
	 * @return the userRating
	 */
	public String getUserRating() {
		return userRating;
	}
	/**
	 * @return the directors
	 */
	public List<String> getDirector() {
		return directors;
	}
	/**
	 * @return the writers
	 */
	public List<String> getWriters() {
		return writers;
	}
	/**
	 * @return the releaseDate
	 */
	public String getReleaseDate() {
		return releaseDate;
	}
	/**
	 * @return the tagLine
	 */
	public String getTagLine() {
		return tagLine;
	}
	/**
	 * @return the plot
	 */
	public String getPlot() {
		return plot;
	}
	/**
	 * @return the plotKeyWords
	 */
	public List<String> getPlotKeyWords() {
		return plotKeyWords;
	}
	/**
	 * @return the userReviews
	 */
	public String getUserReviews() {
		return userReview;
	}
	
	/**
	 * @return the castMembers
	 */
	public List<Cast> getCastMembers() {
		return castMembers;
	}
	/**
	 * @return the genres
	 */
	public List<String> getGenres() {
		return genres;
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int hashCode() {
		return HashCodeBuilder.reflectionHashCode(this);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final boolean equals(final Object obj) {
		if(obj==this){
			return true;
		}
		if(!(obj instanceof ImdbResult)){
			return false;
		}
		ImdbResult imdbResultToCheck = (ImdbResult)obj;
		return EqualsBuilder.reflectionEquals(this, imdbResultToCheck);
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String toString() {
		return ReflectionToStringBuilder.toString(this);
	}
	/***
	 * Builder class of {@link ImdbResult}.
	 * @author Siebe
	 */
	public static class Builder{
		/**
		 * The url of the cover image.
		 */
		private String coverUrl = "";
		/**
		 * The imdb title of the movie.
		 */
		private String title = "";
		/**
		 * The year the movie was made.
		 */
		private String year = "";
		/**
		 * The user rating the movie recieved.
		 */
		private String userRating = "";
		/**
		 * The release date of the movie.
		 */
		private String releaseDate = "";
		/**
		 * The release date of the movie.
		 */
		private String tagLine = "";
		/**
		 * The plot of the movie.
		 */
		private String plot = "";
		/**
		 * The plot key words of the movie.
		 */
		private List<String> plotKeyWords ;
		/**
		 * The best movie review of the movie.
		 */
		private String userReview = "";
		/**
		 * The directors of the movie.
		 */
		private List<String> directors = new ArrayList<String>();
		/**
		 * The writers of the movie.
		 */
		private List<String> writers = new ArrayList<String>();;
		/**
		 * The cast members of the movie.
		 */
		private List<Cast> castMembers = new ArrayList<Cast>();
		/**
		 * The genres of of the movie.
		 */
		private List<String> genres = new ArrayList<String>();
		
		/**
		 * Constructor.
		 */
		public Builder(){
			super();
		}
		
		/**
		 * Builder method for the coverUrl.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder coverUrl(String val){
			this.coverUrl = val;
			return this;
		}
		/**
		 * Builder method for the title.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder title(String val){
			title = val;
			return this;
		}
		/**
		 * Builder method for the year.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder year(String val){
			year = val;
			return this;
		}
		/**
		 * Builder method for the userRating.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder userRating(String val){
			userRating = val;
			return this;
		}
		/**
		 * Builder method for the directors.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder directors(List<String> val){
			directors = val;
			return this;
		}
		/**
		 * Builder method for the writers.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder writers(List<String> val){
			writers = val;
			return this;
		}
		/**
		 * Builder method for the releaseDate.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder releaseDate(String val){
			releaseDate = val;
			return this;
		}
		/**
		 * Builder method for the tagLine.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder tagLine(String val){
			tagLine = val;
			return this;
		}
		/**
		 * Builder method for the plot.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder plot(String val){
			plot = val;
			return this;
		}
		/**
		 * Builder method for the plotKeyWords.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder plotKeyWords(List<String> val){
			plotKeyWords = val;
			return this;
		}
		/**
		 * Builder method for the userReview.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder userReview(String val){
			userReview = val;
			return this;
		}
		/**
		 * Builder method for the castMembers.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder castMembers(List<Cast> val){
			castMembers = val;
			return this;
		}
		/**
		 * Builder method for the genres.
		 * @param val The value to set.
		 * @return The builder.
		 */
		public Builder genres(List<String> val){
			genres = val;
			return this;
		}
		
		/**
		 * Build the {@link ImdbResult}.
		 * @return The {@link ImdbResult}.
		 */
		public ImdbResult build(){
			return new ImdbResult(this);
		}
	}
}
